## with thanks to the great SEVO,
## this routine as well as screen output has been completely rewritten to suit the VISA mod

from CvPythonExtensions import *
import Popup as PyPopup

import CvUtil
import PyHelpers
import CvCameraControls
import CvConfigParser
import CvTechLeakSplashScreen



gc = CyGlobalContext()


def loadConfigurationData():
        
	global iTechRate                        # iTechPercentModifier indicates what percent of tech knowledge may be passed to trading partners
	iTechRate = 0.001

	# loads the ViSa mod ini file
	config = CvConfigParser.CvConfigParser("ViSa_v3.ini")

	# If we actually were able to open the "ViSa_v3.ini" file then read in the values.
	# otherwise we'll keep the default values that were set at the top of this file.
	if(config != None):
		iTechRate = config.getfloat("Techleak Mod","Tech percent modifier", 0.001)
	
# globals
#################################################
class TechLeak:

	def __init__(self):
		
		loadConfigurationData()		

		# initialize the messages for the leaking of techs
		self.techLeakMessageLeft = {}
		for iPlayer in range (gc.getMAX_PLAYERS()+1):
			self.techLeakMessageLeft[iPlayer] = "\n<font=4>You haven't leaked any Research points yet</font>\n"

		# initialize the messages for the recieving of techs
		self.techLeakMessageRight = {}
		for iPlayer in range (gc.getMAX_PLAYERS()+1):
			self.techLeakMessageRight[iPlayer] = "\n<font=4>You haven't recieved any Research points yet</font>\n"


		# no techleak since start or load
		self.firstTechSend = False

		# Modify iTechPercentModifier to match game speed (originally tested for marathon, thus the reason for 1200 factor
		if (CyGame().getEstimateEndTurn() > 0):
			self.iTechPercentModifier = iTechRate * 1200 / CyGame().getEstimateEndTurn()
		else:
			self.iTechPercentModifier = iTechRate
		# else do nothing, as it's already set for a long game.

		# Array for Civ civics
		self.m_paeDisplayCivics = []


	def doLoadGame(self, argsList):
		for iPlayer in range (gc.getMAX_PLAYERS()):
			bTechleakOccur = gc.getPlayer(iPlayer).getTechLeakOccured()
			bTechleakSend = gc.getPlayer(iPlayer).getTechLeakSend()
			if ( bTechleakOccur and bTechleakSend ):
				self.techLeakMessageLeft[iPlayer] = "\n<font=4>You have leaked Research points last time!</font>\n"
			
		for iPlayer in range (gc.getMAX_PLAYERS()):
			bTechleakOccur = gc.getPlayer(iPlayer).getTechLeakOccured()
			bTechLeakRecieved = gc.getPlayer(iPlayer).getTechLeakRecieved()
			if ( bTechleakOccur and bTechLeakRecieved ):
				self.techLeakMessageRight[iPlayer] = "\n<font=4>You have recieved Research points last time!</font>\n"
				
	def getTechLeakMessageLeft(self, iPlayer):
	
		return self.techLeakMessageLeft[iPlayer]

	def getTechLeakMessageRight(self, iPlayer):
	
		return self.techLeakMessageRight[iPlayer]

	def doTechLeakByTrade(self, argsList):
		iGameTurn, iPlayer = argsList
		
		# make sure the messages are cleared each turn before appending any textstrings to them
		self.techLeakMessageLeft[iPlayer] = ''
		self.techLeakMessageRight[iPlayer] = ''
		
		pPlayer = gc.getPlayer(iPlayer)
		pTeam = gc.getTeam(pPlayer.getTeam())
		
		if (pPlayer.isNone() or pPlayer.isBarbarian()):
			return


##############################################################################
########   Check if Civic disables Technology from leaking    ################
##############################################################################

		self.m_paeDisplayCivics = []

		noTechLeakCivicEnabled = False
		
		for iCivicOptionArray in range (gc.getNumCivicOptionInfos()):
			self.m_paeDisplayCivics.append(pPlayer.getCivics(iCivicOptionArray));

		for iCivicOption in range(gc.getNumCivicOptionInfos()):
			for jCivic in range(gc.getNumCivicInfos()):

				if (gc.getCivicInfo(jCivic).getCivicOptionType() == iCivicOption):
							
					if (self.m_paeDisplayCivics[iCivicOption] == jCivic):
						if (gc.getCivicInfo(jCivic).isNoTechLeak() and pPlayer.canDoCivics(jCivic)):
							szName = "" + gc.getCivicInfo(jCivic).getDescription()                                                        
							self.techLeakMessageLeft[iPlayer] += "\n<font=4>No Technology Leak occurs with " + szName
							noTechLeakCivicEnabled = True
		if ( noTechLeakCivicEnabled == True ):
			return
							


##############################################################################
##############################################################################
##############################################################################

		newMessage = []
		iAmtToAddCount = 0  #check if we are leaking any tech at all to any player on any tech from any city and reset it each turn
		
				
		# Loop through all players
		# Because of the way tech leak was designed, we have to cycle through players first, then techs, then cities, etc.  
		# This is because trade routes are asymmetric between civs!  I.e., a large civ might recieve a trade route from a small civ 
		# that does not recipricate the link!
		for iTargetPlayer in range(gc.getMAX_PLAYERS()):
			pTargetPlayer = gc.getPlayer(iTargetPlayer)
			MessageCount = 0
			bTechLeakTarget = False   ##for the leaking civ
			
						
			# Loop through all techs
			for iTechCursor in range(gc.getNumTechInfos()):
		
				# If pPlayer has tech iTechCursor
				if (pTeam.isHasTech(iTechCursor)):
				
					
				
					# If pTargetPlayer is a valid target to pass techs and does not yet have iTechCursor
					# This is a damn long If! pTargetPlayer.canResearch(iTechCursor, false) and \ and (pTeam.isOpenBorders(pTargetPlayer.getTeam()))
					if (not pTargetPlayer.isNone() and not pTargetPlayer.isBarbarian() and pTargetPlayer.isAlive() and \
					not gc.getTeam(pTargetPlayer.getTeam()).isHasTech(iTechCursor)):
					
						# TotalTradeRoutes = 0
					
						# Okay, leaking some here.
						pTeam = gc.getTeam(pPlayer.getTeam())
						
						# Initialize amount to add variable, this will keep track of total points to add to this tech
						iAmtToAdd = 0						
						# Cycle through all of pPlayer's cities
						for iCityCursor in range(pPlayer.getNumCities()):
							pPlayerCity = pPlayer.getCity(iCityCursor)
							# If pPlayerCity is valid
							if (not pPlayerCity.isNone()):
								pTargetTeam = gc.getTeam(pTargetPlayer.getTeam())
								# Loop through all of pPlayerCity's trade routes
								for iTargetCityCursor in range(pPlayerCity.getTradeRoutes()):
									pTargetCity = pPlayerCity.getTradeCity(iTargetCityCursor)

									# If pTargetCity is valid, and pTargetCity is owned by pTargetPlayer
									if (not pTargetCity.isNone() and pTargetCity.getOwner() == pTargetPlayer.getID()):
										# Add percentage into amount to add
										iAmtToAdd = iAmtToAdd + (pTargetTeam.getResearchCost(iTechCursor) * self.iTechPercentModifier)
										
										# TotalTradeRoutes += 1

										# Can never auto-grant, so set to 1 less if meets or exceeds amount needed
										if (pTargetTeam.getResearchProgress(iTechCursor) + iAmtToAdd >= pTargetTeam.getResearchCost(iTechCursor)):
											iAmtToAdd = pTargetTeam.getResearchCost(iTechCursor) - pTargetTeam.getResearchProgress(iTechCursor) - 1

						# Sevo's Balancer					
																		
						AA = pPlayer.getTechScore()
						BB = pTargetPlayer.getTechScore()
						
						if ((AA + BB) != 0):						
							if (AA > (BB*1.6)):
								iAmtToAdd = iAmtToAdd * 0.6
								ffactor = 0.6
							elif (AA > (BB*1.4)):
								iAmtToAdd = iAmtToAdd * 0.4
								ffactor = 0.4
							elif (AA > (BB*1.2)):
								iAmtToAdd = iAmtToAdd * 0.2
								ffactor = 0.2
							else:	
								iAmtToAdd = iAmtToAdd * 0.1
								ffactor = 0.1
						else:  # This really shouldn't occur 
							iAmtToAdd = 1

							
						
						# Clean up the number
						# The +0.5 changes the int() function into a rounded number instead (i.e., 1.6 becomes 2, not 1)						
						iAmtToAdd = int(3 * iAmtToAdd + 0.5)						

						# If there are points to be added, do so
						if (iAmtToAdd > 0):
							pTargetTeam.changeResearchProgress(iTechCursor, iAmtToAdd, pTargetPlayer.getID())

							#did techleak occured to this specific targetplayer?
							bTechLeakTarget = True
							
							# Player has leaked tech for the first time in game, set this to true so the "no techleak has occured yet" message will be disregarded
							self.firstTechSend = True

							
							# send message to the CvMainInterface that the techleak has occured for the first time
							pPlayer.setTechLeakSend(True)
							
							# make sure the reciever knows he got tech for the first time since starting the game, so the "not recieved any tech yet" message will be disregarded
							pTargetPlayer.setTechLeakRecieved(True)
							#self.firstTimeTechRecieve[pTargetPlayer.getID()] = True

							
							iAmtToAddCount = 1  # are we leaking tech this turn?
							MessageCount += 1   # counter so we only export the tech recieved/send message once for each player
							
							# make sure that the message is only printed on screen once per new playerleaking tech
							if (MessageCount == 1):
								mBuff = self.techLeakMessageRight[pTargetPlayer.getID()]							
								mBuff = mBuff + "<font=4>Research points leaked from %s:</font>\n\n" %(pPlayer.getName())
								self.techLeakMessageRight[pTargetPlayer.getID()] = mBuff							
													
							# Outgoing message--to the civ that just received tech
							mBuff = self.techLeakMessageRight[pTargetPlayer.getID()]							
							mBuff = mBuff + "%s: +%s Research points\n" %(gc.getTechInfo(iTechCursor).getDescription(), iAmtToAdd)
							# mBuff = mBuff + "\t(You:%s vs Them:%s, ffactor=%s, TTR=%s)\n" %(BB,AA,ffactor, TotalTradeRoutes)
							self.techLeakMessageRight[pTargetPlayer.getID()] = mBuff

							# make sure that the message is only printed on screen once at the beginning
							if (MessageCount == 1):
								mBuff = self.techLeakMessageLeft[pPlayer.getID()]
								mBuff = mBuff + "<font=4>Research points leaked to %s:</font>\n\n" %(pTargetPlayer.getName())
								self.techLeakMessageLeft[pPlayer.getID()] = mBuff
																
							# Notice to leaking civ about the leak
							mBuff = self.techLeakMessageLeft[pPlayer.getID()]
							mBuff = mBuff + "%s: +%s Research points \n" %(gc.getTechInfo(iTechCursor).getDescription(), iAmtToAdd)
							# mBuff = mBuff + "\t(You:%s vs Them:%s, ffactor=%s, TTR=%s)\n" %(AA,BB,ffactor, TotalTradeRoutes)							
							self.techLeakMessageLeft[pPlayer.getID()] = mBuff

			#make sure 2 spaces are done between the players listings				
			if (bTechLeakTarget == True):
				#techleak 2 spacing
				mBuff = self.techLeakMessageLeft[pPlayer.getID()]
				mBuff = mBuff + "\n\n"
				self.techLeakMessageLeft[pPlayer.getID()] = mBuff

				#tech recieve 2 spacing
				mBuff = self.techLeakMessageRight[pTargetPlayer.getID()]
				mBuff = mBuff + "\n\n"
				self.techLeakMessageRight[pTargetPlayer.getID()] = mBuff
							
											

								
					    
		# End of Technologies Loop
		# newMessage contains the list of techs

		
		# you are not leaking any research points this turn, send this to the player
		if (iAmtToAddCount == 0 and self.firstTechSend == True ):
			self.techLeakMessageLeft[iPlayer] = "<font=4>You aren't leaking any Research points this turn!</font>\n"


		# as long as no techleak has occured at all in all turns, this will be false and send this information to the player
		#if ( self.firstTechSend == False ):
		#	self.techLeakMessageLeft[iPlayer] = "<font=4>You haven't leaked any Research points yet</font>\n"


		
								
						
		
	def doTrashAll(self, argsList):

		iGameTurn, iPlayer = argsList
	
		# clean the messages
		trash = 1

	def doTechLeakFirst(self, argsList):
		iGameTurn, iPlayer = argsList
				
		if( ( gc.getPlayer(iPlayer).getTechLeakRecieved() or \
		gc.getPlayer(iPlayer).getTechLeakSend() ) and \
		not gc.getPlayer(iPlayer).getTechLeakOccured()):
			
			gc.getPlayer(iPlayer).setTechLeakOccured(True)
			CyInterface().setDirty(InterfaceDirtyBits.MiscButtons_DIRTY_BIT, True)
			# If Techleak is not for humanplayer, don't popup!
			# If we're running in AIAutoPlay mode we don't want these popups to Appear
			# this little if does 2 at once			
			if ( gc.getPlayer(iPlayer).isHuman() ):
				CvTechLeakSplashScreen.CvTechLeakSplashScreen().interfaceScreen(iPlayer)

		

		
	
